﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using VersionComparer.Base;

namespace VersionComparer.Views
{
    public partial class RichTextComparer : UserControl
    {
        Timer initTimer = new Timer();
        public RichTextComparer()
        {
            InitializeComponent();

            richTextBox1.HideSelection = false;
            richTextBox2.HideSelection = false;
            richTextBox1.WordWrap = false;
            
            richTextBox2.WordWrap = false;
            richDetails1.ReadOnly = true;
            richDetails1.HideSelection = false;
            richDetails1.WordWrap = false;

            richDetails2.ReadOnly = true;
            richDetails2.HideSelection = false;
            richDetails2.WordWrap = false;

            richTextBox1.Visible = false;
            richTextBox2.Visible = false;
            //toolStrip2.Text = "";
            //toolStrip1.Text = "";
            
        }

        public RichTextComparer(bool lockControls): this()
        {
            locked = lockControls;
            richTextBox2.SelectionChanged += richTextBox2_SelectionChanged;
            richTextBox1.SelectionChanged += richTextBox1_SelectionChanged;
            richTextBox1.HScroll += richTextBox1_HScroll;
            richTextBox2.HScroll += richTextBox2_HScroll;
            richTextBox1.VScroll += richTextBox1_VScroll;
            richTextBox2.VScroll += richTextBox2_VScroll;
            splitContainer1.SplitterDistance = splitContainer1.Width/2;
        }

        bool locked = true;
        public bool Locked
        {
            get
            {
                return locked;
            }
            set
            {
                locked = value;
                if (locked)
                    SynchronizeSelection(richTextBox1, richTextBox2);
            }
        }
        void richTextBox2_SelectionChanged(object sender, EventArgs e)
        {
            if (lockdisabled)
                return;
            UpdateStatus();
            SynchronizeSelection(richTextBox2, richTextBox1);
        }


        private void SynchronizeSelection(RichTextBox source, RichTextBox destination)
        {
            if (!Locked)
                return;
            int firstSelectedLine = source.GetLineFromCharIndex(source.SelectionStart);
            int lastSelectedLine = source.GetLineFromCharIndex(source.SelectionStart + source.SelectionLength);
            int firstSelectedChar = source.SelectionStart - source.GetFirstCharIndexFromLine(firstSelectedLine);
            int lastSelectedChar = source.SelectionStart + source.SelectionLength - source.GetFirstCharIndexFromLine(lastSelectedLine);

            int destinationFirstLine = firstSelectedLine;// source.Lines.Length == 0 ? 0 : firstSelectedLine * destination.Lines.Length / source.Lines.Length;
            int destinationLastLine = lastSelectedLine; //source.Lines.Length == 0 ? 0 : lastSelectedLine * destination.Lines.Length / source.Lines.Length;
            if (destinationFirstLine >= destination.Lines.Length)
                destinationFirstLine = destination.Lines.Length - 1;
            if (destinationLastLine >= destination.Lines.Length)
                destinationLastLine = destination.Lines.Length - 1;

            if (destinationFirstLine < 0)
                destinationFirstLine = 0;
            if (destinationLastLine < 0)
                destinationLastLine = 0;
            if (destination.Lines.Length == 0)
                return;
            //int selectionStart = source.Lines[firstSelectedLine].Length== 0? 0:destination.GetFirstCharIndexFromLine(destinationFirstLine) + firstSelectedChar * destination.Lines[destinationFirstLine].Length / source.Lines[firstSelectedLine].Length;
            //int selectionEnd = source.Lines[lastSelectedLine].Length== 0? 0:destination.GetFirstCharIndexFromLine(destinationLastLine) + lastSelectedChar * destination.Lines[destinationLastLine].Length / source.Lines[lastSelectedLine].Length;
            int selectionStart = destination.GetFirstCharIndexFromLine(destinationFirstLine) + (firstSelectedChar > destination.Lines[destinationFirstLine].Length ? destination.Lines[destinationFirstLine].Length : firstSelectedChar);
            int selectionEnd = destination.GetFirstCharIndexFromLine(destinationLastLine) + (lastSelectedChar > destination.Lines[destinationLastLine].Length ? destination.Lines[destinationLastLine].Length : lastSelectedChar);
            int selectionLength = selectionEnd - selectionStart;
            if (destination.SelectionStart != selectionStart || destination.SelectionLength != selectionLength)
                destination.Select(selectionStart, selectionLength);
        }
        void richTextBox1_SelectionChanged(object sender, EventArgs e)
        {
            if (lockdisabled)
                return;
            UpdateStatus();
            
            SynchronizeSelection(richTextBox1, richTextBox2);
        }

        public RtfBuilder Rtf1
        {
            get;
            set;
        }
        public RtfBuilder Rtf2
        {
            get;
            set;
        }
        bool lockdisabled = false;
        private void UpdateStatus()
        {
            if (lockdisabled)
                return;
            lockdisabled = true;
            richDetails1.Rtf = richTextBox1.SelectedRtf.Replace ("\\par\r\n","");
            richDetails2.Rtf = richTextBox2.SelectedRtf.Replace("\\par\r\n", "");
            lockdisabled = false;
            //toolStrip1.Text = richTextBox1.SelectedText;
            //toolStrip2.Text = richTextBox2.SelectedText;
        }
        void richTextBox2_VScroll(object sender, EventArgs e)
        {
            
            if (!Locked)
                return;
            if (richTextBox2.VerticalScrollPosition != richTextBox1.VerticalScrollPosition)
                richTextBox1.VerticalScrollPosition = richTextBox2.VerticalScrollPosition;
        }
        void richTextBox1_VScroll(object sender, EventArgs e)
        {
            
            if (!Locked)
                return;
            if ( richTextBox2.VerticalScrollPosition != richTextBox1.VerticalScrollPosition)
                richTextBox2.VerticalScrollPosition = richTextBox1.VerticalScrollPosition;
        }
        void richTextBox2_HScroll(object sender, EventArgs e)
        {
            if (!Locked)
                return;
            if (richTextBox2.HorizontalScrollPosition != richTextBox1.HorizontalScrollPosition)
                richTextBox1.HorizontalScrollPosition = richTextBox2.HorizontalScrollPosition;
        }
        void richTextBox1_HScroll(object sender, EventArgs e)
        {
            if (!Locked)
                return;
            if (richTextBox2.HorizontalScrollPosition != richTextBox1.HorizontalScrollPosition)
                richTextBox2.HorizontalScrollPosition = richTextBox1.HorizontalScrollPosition;
        }

        protected override void OnLoad(EventArgs e)
        {
            richTextBox1.Visible = false;
            richTextBox2.Visible = false;
            base.OnLoad(e);
            initTimer.Tick += initTimer_Tick;
            initTimer.Interval = 10;
            initTimer.Start();
            

        }

        void SetTextBoxRTF ( ExtendedRichTextBox richTextBox , RtfBuilder rtf )
        {
            richTextBox.BeginUpdate();
            
            if (rtf != null)
            {
                rtf.Protect = true;
                string rtfText = rtf.Rtf;
                if (rtf.IsOverflow)
                    rtfText += "\\par\r\n.\\par\r\n.\\par\r\n.";
                richTextBox.Rtf = rtfText;
            }
        }
        void initTimer_Tick(object sender, EventArgs e)
        {
            initTimer.Stop();

            SetTextBoxRTF(richTextBox1, Rtf1);
            SetTextBoxRTF(richTextBox2, Rtf2);
            richTextBox1.Visible = true;
            richTextBox2.Visible = true;
        }
        private void RichTextComparer_Load(object sender, EventArgs e)
        {

        }

        private void splitContainer2_SplitterMoved(object sender, SplitterEventArgs e)
        {

        }

        private void richTextBox4_TextChanged(object sender, EventArgs e)
        {

        }

        private void richTextBox1_TextChanged(object sender, EventArgs e)
        {

        }
    }
}
